﻿using System;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace tjb.Utility.Template
{
    /// <summary>
    /// 
    /// </summary>
    public class TempletConvert
    {
        ///   <summary>   
        ///   根据属性名获取属性的值并返回值   
        ///   </summary>   
        ///   <param   name="ClassInstance">类实例</param>   
        ///   <param   name="PropertyName">属性名</param>   
        ///   <returns></returns>   
        protected object GetPropertyValue(object ClassInstance, string PropertyName)
        {
            Type myType = ClassInstance.GetType();
            PropertyInfo myPropertyInfo = myType.GetProperty(PropertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            if (myPropertyInfo == null)
                return null;
            return myPropertyInfo.GetValue(ClassInstance, null);
        }
        /// <summary>
        /// 根据字段名获取字段的值并返回值   
        /// </summary>
        /// <param name="ClassInstance"></param>
        /// <param name="FieldName"></param>
        /// <returns></returns>
        protected object GetFieldValue(object ClassInstance, string FieldName)
        {
            Type myType = ClassInstance.GetType();
            System.Reflection.FieldInfo myFieldInfo = myType.GetField(FieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            if (myFieldInfo == null)
                return null;
            return myFieldInfo.GetValue(ClassInstance);
        }
        /// <summary>
        /// 根据属性名或字段名获取属性或字段的值并返回值   
        /// </summary>
        /// <param name="ClassInstance"></param>
        /// <param name="Name"></param>
        /// <returns></returns>
        protected string GetValue(object ClassInstance, string Name)
        {
            if (ClassInstance == null)
                return "";
            Name = Name.Trim();
            object value = GetPropertyValue(ClassInstance, Name);
            if (value == null)
                value = GetFieldValue(ClassInstance, Name);
            if (value == null)
                return "[模板错误。" + ClassInstance.GetType().FullName + "未找到‘" + Name + "’字段或属性名称。]";
            return Converter(value);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dateFormat"></param>
        /// <param name="decimalFormat"></param>
        /// <param name="doubleFormat"></param>
        public TempletConvert(string dateFormat,
            string decimalFormat,
            string doubleFormat)
        {
            this.DateFormat = dateFormat;
            this.DecimalFormat = decimalFormat;
            this.DoubleFormat = doubleFormat;
        }
        /// <summary>
        /// 
        /// </summary>
        public TempletConvert() { }
        /// <summary>
        /// 
        /// </summary>
        public string DateFormat = "yyyy年MM月dd日";
        /// <summary>
        /// 
        /// </summary>
        public string DecimalFormat = "0.00";
        /// <summary>
        /// 
        /// </summary>
        public string DoubleFormat = "0.00";
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected string Converter(object value)
        {
            if (null == value)
                return "";
            if (value is DateTime)
                return ((DateTime)value).ToString(DateFormat);
            if (value is decimal)
                return ((decimal)value).ToString(DecimalFormat);
            if (value is double)
                return ((double)value).ToString(DoubleFormat);
            if (value is Enum)
            {
               return  EnumDescConverter.GetEnumDescription((Enum)value);
            }
            return value.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        protected const string Pattern = @"<%=(?<name>[\s|\S]*?)%>";
        /// <summary>
        /// 
        /// </summary>
        protected static Regex reg = new Regex(Pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strInput"></param>
        /// <param name="ClassInstance"></param>
        /// <returns></returns>
        public string ConvertTemplate(String strInput, object ClassInstance)
        {
            MatchCollection mc = reg.Matches(strInput);
            StringBuilder temp = new StringBuilder(strInput);
            int i = mc.Count;
            while (i-- > 0)
            {
                Match m = mc[i];
                string name = m.Groups["name"].Value;
                temp = temp.Replace(m.Value, GetValue(ClassInstance, name), m.Index, m.Length);
            }
            return temp.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="ClassInstance"></param>
        /// <returns></returns>
        public StringBuilder ConvertTemplate(StringBuilder sb, object ClassInstance)
        {
            MatchCollection mc = reg.Matches(sb.ToString());

            StringBuilder temp = sb;
            int i = mc.Count;
            while (i-- > 0)
            {
                Match m = mc[i];
                string name = m.Groups["name"].Value;
                temp = temp.Replace(m.Value, GetValue(ClassInstance, name), m.Index, m.Length);
            }
            return temp;
        }
    }
}
